package com.gticket.orderservice.handler;

import com.gticket.orderservice.pojo.*;
import com.gticket.orderservice.service.ActualSeatService;
import com.gticket.orderservice.service.OrderItemService;
import com.gticket.orderservice.service.OrderService;
import com.rabbitmq.client.Channel;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.List;
import java.util.UUID;

/**
 * @Author: 伴你时光尽头
 * @Date: 2019/11/18 16:12
 */
@Api(value = "OrderHandler", tags = "订单")
@RestController
@Slf4j
public class OrderHandler {
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private ActualSeatService actualSeatService;
    @Autowired
    private RabbitTemplate template;

    @Autowired
    private List<OrderItems> items;

    @ApiOperation(value = "查询所有订单，用于后台查询", notes = "传入databasename", tags = "订单")
    //查询所有订单
    @GetMapping("/getallorders")
    public ResponseData getAll(@ApiParam(name = "数据库名", value = "数据库名", required = true) String databasename) {

        Orders orders = new Orders();
        orders.setDatabasename(databasename);
        log.error(databasename + "后台管理查询所有订单");
        return new ResponseData(200, "响应data为orders集合", orderService.getAll(orders));
        //        return orderService.getAll(orders);
    }


    //创建订单
    @CrossOrigin(origins = "*")
    @ApiOperation(value = "创建订单", notes = "传入数据库名，用户id，影院分院影院id，订单项集合", tags = "订单")
    @GetMapping("/createorder")
    public ResponseData createOrder(@ApiParam(name = "订单项集合", value = "", required = true) String msg, HttpServletRequest request) throws Exception {
        items.clear();
        String[] sequence1 = msg.split("k");//将数据分割开
        String databasename = sequence1[0];
        Integer fs_id = Integer.valueOf(sequence1[1]);
        String[] sequence2 = null;
        for(int i = 2;i<sequence1.length;i++){
            sequence2 = sequence1[i].split("-");
            Integer row = Integer.valueOf(sequence2[0]);
            Integer col = Integer.valueOf(sequence2[1]);
            items.add(new OrderItems(databasename,fs_id,row,col));
        }
        //创建订单号
        String order_num = UUID.randomUUID().toString().replaceAll("-", "");
        log.error("创建订单" + order_num);
        //获取session
        HttpSession session = request.getSession();
        //从session中获取user_id
        Integer user_id = (Integer) session.getAttribute("user_id");
        Integer cinema_id = null;
        String cinema_name = null;
        if (items != null) {
            /***************************************************************************/
            //根据订单项中的排片表id  fs_id  查询影院id
            cinema_id = orderItemService.selectCinema_idByFs_id(items.get(0));
            /***************************************************************************/
            cinema_name = orderItemService.selectCinema_nameByFs_id(items.get(0));
        }
        Integer order_id = null;
        Integer as_id = null;
        //创建订单 并返回订单编号  order_id
        if (cinema_id != null) {
            order_id = orderService.addOrder(new Orders(items.get(0).getDatabasename(), order_num, user_id, cinema_id, cinema_name));
        }
        if (order_id != null) {
            for (OrderItems item : items) {
                log.error("订单" + order_num + "订单项为" + item.toString());
                item.setOrder_id(order_id);
                //创建订单项
                orderItemService.addOrderItem(item);

                //根据订单项  将座位表修改
                ActualSeat actualSeat = actualSeatService.selectActualSeatByAs_id(item);
                as_id = actualSeat.getAs_id();
                //通过反射获取当前订单中座位的行
                Class<?> ActualSeat = Class.forName("com.gticket.orderservice.pojo.ActualSeat");
                Object obj = ActualSeat.newInstance();
                Method method = ActualSeat.getDeclaredMethod("getRow_" + item.getRow(), null);
                String temp = (String) method.invoke(actualSeat);//指定行
                StringBuffer stemp = new StringBuffer(temp);
                stemp.replace(item.getCol(), item.getCol()+1, "2");
                //反射设置对应行
                actualSeat = new ActualSeat();
                actualSeat.setDatabasename(item.getDatabasename());

                Method method1 = ActualSeat.getDeclaredMethod("setRow_" + item.getRow(), String.class);
                method1.invoke(actualSeat, stemp.toString());
                actualSeat.setAs_id(as_id);
                actualSeatService.changeRow(actualSeat);
                actualSeat = null;
            }
            //将当前user  当前电影场次  之前未支付的订单直接取消
            orderService.cancelInvalidOrder(orderService.getOrdersByOrder_num(new Orders(databasename,order_num)));

            //将数据发送到rabbitmq消息队列  创建消费者
            addOrder(new Orders(items.get(0).getDatabasename(), order_num, user_id, cinema_id, cinema_name));
//            return "true";
            return new ResponseData(200, "成功响应data为订单编号", order_num);
        }
//        return "false";
        return new ResponseData(200, "失败响应data为null", null);
    }


    public void addOrder(Orders orders) {
        log.error("发送{{{" + orders + "}}}到消息队列");
        template.convertAndSend(ExchangeName.DEAD_LETTER, RoutingKey.DELAY_KEY, orders);
    }


    //根据订单编号查询订单

    /**
     * @param orders 封装订单id和databasename
     * @return
     */
    @CrossOrigin(origins = "*")
    @ApiOperation(value = "通过order_id查询订单信息，用于订单支付页面", notes = "传入databasenamehe 和 order_id", tags = "订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "order_id", value = "2", required = true),
            @ApiImplicitParam(name = "databasename", value = "filmforcustomer", required = true)
    })
    @GetMapping("/getorderbynum")
    public ResponseData getOrdersByOrder_num(@ApiParam(name = "订单pojo", value = "databsename和order_id自动封装", required = true) Orders orders) {
        System.out.println(orders);

        Orders order = orderService.getOrdersByOrder_num(orders);
        log.error("通过订单num查询订单:" + orders.getOrder_num());
        return new ResponseData(200, "返回data为：订单对象  对象中订单项为list集合", order);
    }

    //根据用户查询订单

    /**
     * @param orders 封装user_id和databasename
     * @return
     */
    @CrossOrigin(origins = "*")
    @ApiOperation(value = "通过user_id查询订单信息", notes = "传入databasenamehe 和 user_id", tags = "订单")
    @GetMapping("/getorderbyuser_id")
    public ResponseData getOrderBYUser_id(@ApiParam(name = "订单pojo", value = "databsename和user_id自动封装", required = true) Orders orders,HttpSession session) {
        if(session.getAttribute("user_id")!=null){
            orders.setUser_id((Integer)session.getAttribute("user_id"));
        }
        System.out.println(orders);
        List<Orders> orderss = orderService.getOrderByUser_id(orders);
        log.error("用户id为" + orders.getUser_id() + "查询其所有订单");
        return new ResponseData(200, "返回data为：订单对象  对象中订单项为list集合", orderss);
    }



//    /**
//     * 取消订单
//     * <p>
//     * <p>
//     * <p>
//     * 要配合退款   配合退款
//     *
//     * @param orders 封装订单id和databasename
//     * @return
//     */
//    @ApiOperation(value = "取消订单", notes = "传入databasenamehe 和 order_id", tags = "订单")
//    @GetMapping("/cancelorder")
//    public ResponseData cancelOrder(@ApiParam(name = "订单pojo", value = "databsename和user_id自动封装", required = true) Orders orders) {
//        //修改状态为已取消
//        orderService.changeOrderStateByOrder_id(orders);
//        log.error(orders.getOrder_id() + "id  订单退款，修改状态为已取消");
//        Orders order = orderService.getOrderById(orders);
//        System.out.println(order);
//        return new ResponseData(200, "返回data为修改状态后的order", order);
//    }


    /**
     * 根据订单创建时间查询订单  返回订单集合
     *
     * @param orders 封装订单id和databasename
     * @return
     */
    @CrossOrigin(origins = "*")
    @ApiOperation(value = "根据时间查询订单，返回order集合", notes = "传入databasenamehe 和 create_time,lastTime", tags = "订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "create_time", value = "2019-12-31", required = true),
            @ApiImplicitParam(name = "lastTime", value = "2019-12-31", required = true),
            @ApiImplicitParam(name = "databasename", value = "filmforcustomer", required = true)
    })
    @GetMapping("/getorderbycreate_time")
    public ResponseData getOrderBYCreate_time(@ApiParam(name = "订单pojo", value = "databsename和create_time自动封装", required = true) Orders orders) {
        List<Orders> orderss = orderService.getOrderBYCreate_time(orders);
        log.error("后台管理查询" + orders.getCreate_time() + "到" + orders.getLastTime() + "之间的订单");
        return new ResponseData(200, "返回data为修改状态后的order", orderss);
    }


    /****************************营业额未完成********************************************/
    //统计营业额
    @CrossOrigin(origins = "*")
    @GetMapping("/getrevenue")
    public ResponseData getRevenue(Orders orders) {
        return new ResponseData(200, "返回data为修改状态后的order", orders);
    }


    //死信监听
    @RabbitListener(queues = QueueName.ImmediateQueue)
    public void process2(Message message, Channel channel, Orders orders) {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            if (orderService.getState(orders) != 0) {
                channel.basicNack(deliveryTag, false, false);
            } else {
                log.error("订单延时结束 死信处理" + orders);
                //如果状态未被修改  则修改状态位已失效
                log.error("订单" + orders.getOrder_num() + "失效修改状态为已失效");
                orderService.updateState(orders);
                //释放座位
                Integer as_id = null;
                List<OrderItems> items = orderItemService.getItemsByOrder_num(orders);
                for (OrderItems item : items) {
                    item.setDatabasename(orders.getDatabasename());
                    log.error("座位释放row：" + item.getRow() + "col:" + item.getCol());
                    //根据订单项  将座位表修改
                    ActualSeat actualSeat = actualSeatService.selectActualSeatByAs_id(item);
                    as_id = actualSeat.getAs_id();
                    //通过反射获取当前订单中座位的行
                    Class<?> ActualSeat = Class.forName("com.gticket.orderservice.pojo.ActualSeat");
                    Object obj = ActualSeat.newInstance();
                    Method method = ActualSeat.getDeclaredMethod("getRow_" + item.getRow(), null);
                    String temp = (String) method.invoke(actualSeat);//指定行
                    StringBuffer stemp = new StringBuffer(temp);
                    stemp.replace(item.getCol(), item.getCol()+1, "1");
                    //反射设置对应行
                    actualSeat = new ActualSeat();
                    actualSeat.setDatabasename(item.getDatabasename());
                    Method method1 = ActualSeat.getDeclaredMethod("setRow_" + item.getRow(), String.class);
                    method1.invoke(stemp.toString());
                    actualSeat.setAs_id(as_id);
                    actualSeatService.changeRow(actualSeat);
                    actualSeat = null;
                }
                channel.basicAck(deliveryTag, false);
            }
        } catch (Exception e) {

        }
    }



    //死信监听    电影结束 后修改未使用订单为已完成
    @RabbitListener(queues = "dlx_queue1_schedule_end")
    public void process3(Message message, Channel channel, byte[] msg) {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            String[] info = new String(msg).split(",");
            String databasename = info[0];
            Integer fs_id = Integer.valueOf(info[1]);

            System.out.println(databasename+"     "+fs_id);
            //电影完成之后修改未观看的影片为已完成
            orderService.updateStateComplete(new OrderItems(databasename,fs_id));
                channel.basicAck(deliveryTag, false);

        } catch (Exception e) {

        }
    }



    //取票
    //封装databasename和ticketnum   3已取票 返回订单项信息
    @CrossOrigin(origins = "*")
    @GetMapping("/ticketget")
    public ResponseData takeTicket(Orders orders){
        //返回订单项信息
        Orders orders1 = orderService.getOrderByTicketnum(orders);
        //修改订单状态为已取票
        orderService.updataStateToAlreadyTake(orders);
        return new ResponseData(200,"取票成功，返回订单信息",orders1);
    }


}
